<?php
/**
 * Created by 链行天下.
 * Users: tangjianing(990921093@qq.com)
 * Date: 2018/12/21 18:39
 */

namespace App\Tools;


/**
 * 生产者类
 */
class AsynMessagePublisher
{
    private $config = array();
    private $conn = Null;
    private $channel = Null;
    private $exchange = Null;
    public $is_ready = false;

    /**
     * 创建连接，并指定交换机
     * @param array $config RabbitMQ服务器信息
     * @param string $e_name 交换机名称
     * @return void
     */
    public function __construct($config, $e_name)
    {
        if (!($config && $e_name)) return false;
        $this->config = $config;
        if (!self::connect()) return false;
        $this->channel = new \AMQPChannel($this->conn);
        $this->establishExchange($e_name);
        $this->is_ready = true;
    }

    /**
     * 发送消息
     * @param string $msg 消息体
     * @param string $k_route 路由键
     * @return int / false
     */
    public function send($msg, $k_route)
    {
        $msg = trim(strval($msg));
        if (!$this->exchange || $msg === '' || !$k_route) return false;
        $ret = $this->exchange->publish($msg, $k_route);
        return $ret;
    }

    // 以下为私有方法，无需手动调用

    /**
     * 创建链接
     * 无法链接时则会自动选择下一个配置项（IP不通的情况下会有5秒等待）
     * @param int $i 配置项索引
     * @return bool
     */
    private function connect($i = 0)
    {
        if (array_key_exists($i, $this->config)) {
            try {
                $this->conn = new \AMQPConnection($this->config[$i]);
                $this->conn->connect();
                $ret = true;
            } catch (\AMQPConnectionException $e) {
                $ret = $this->connect(++$i);
            }
        } else {
            $ret = false;
        }
        return $ret;
    }

    /**
     * 创建交换机
     * @param string $name 名称
     * @return void
     */
    private function establishExchange($name)
    {
        $this->exchange = new \AMQPExchange($this->channel);
        $this->exchange->setName($name);
    }

    public function __destruct()
    {
        if ($this->conn) {
            $this->conn->disconnect();
        }
    }
}